package cn.chinaflame.pagodas.service;

import cn.chinaflame.pagodas.Result.Result;
import cn.chinaflame.pagodas.constant.Sysconst;
import cn.chinaflame.pagodas.dto.MemberRegistDto;
import cn.chinaflame.pagodas.dto.PaMemberDto;
import cn.chinaflame.pagodas.dto.PaMemberNickDto;
import cn.chinaflame.pagodas.entity.PaMember;
import cn.chinaflame.pagodas.enums.CodeEnum;
import cn.chinaflame.pagodas.repository.PaMemberRepository;
import cn.chinaflame.pagodas.req.PaMemberReq;
import cn.chinaflame.pagodas.req.WebRegistDetailReq;
import cn.chinaflame.pagodas.utils.DateTimes;
import cn.chinaflame.pagodas.utils.Digests;
import cn.chinaflame.pagodas.utils.ParamPreconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Objects;


/**
 * @author created by lbq
 * @date 2018年1月5日 下午5:28:43
 **/
@Service
public class PaMemberService {
    private final static Logger log = LoggerFactory.getLogger(PaMemberService.class);
    @Autowired
    private PaMemberRepository paMemberRepository;
    @Autowired
    private IdGeneratorService idGeneratorService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private PaAgentService paAgentService;

    /**
     * 会员注册
     *
     * @param mobile
     * @param loginId
     * @param loginPwd
     * @param email
     * @return
     */
    public MemberRegistDto regist(String mobile, String loginId, String loginPwd, String email) {
        log.info("佛龛会员注册mobile:{},loginId:{},loginPwd:{},email:{}", mobile, loginId, loginPwd, email);
        ParamPreconditions.checkNotEmpty(mobile, CodeEnum.FAIL.getCode(), "会员手机号不能为空");
        ParamPreconditions.checkNotEmpty(loginPwd, CodeEnum.FAIL.getCode(), "密码不能为空");
        ParamPreconditions.checkMobileFmt(mobile);
        if (!Strings.isNullOrEmpty(email))
            ParamPreconditions.checkEmailFmt(email);
        String loginPwdMd5 = Digests.md5DigestAsHex(loginPwd);
        PaMember member = paMemberRepository.findByMobile(mobile);
        ParamPreconditions.checkArgument(member == null || Sysconst.REGIST_FALSE.equals(member.getRegistFlg()),
                CodeEnum.FAIL.getCode(), "用户已注册");
        PaMember loginIdMember = paMemberRepository.findByLoginId(loginId);
        boolean b = loginId == null || loginIdMember == null || mobile.equals(loginIdMember.getMobile())
                || loginId.equals(loginIdMember.getLoginId());
        ParamPreconditions.checkArgument(b, CodeEnum.FAIL.getCode(), "登录名重复");
        if (Strings.isNullOrEmpty(loginId))
            loginId = mobile;
        if (member == null) {
            member = new PaMember();
            String memberId = idGeneratorService.generateMemberId();
            member.setId(memberId);
        }
        member.setLoginId(loginId);
        member.setMobile(mobile);
        member.setLoginPwd(loginPwdMd5);
        member.setEmail(email);
        member = paMemberRepository.saveAndFlush(member);
        MemberRegistDto dto = new MemberRegistDto();
        BeanUtils.copyProperties(member, dto);
        return dto;
    }

    /**
     * 会员登录
     *
     * @param username
     * @param password
     * @return
     */
    public MemberRegistDto login(String username, String password) {
        log.info("佛龛会员登录username:{},password:{}", username, password);
        PaMember entity = null;
        ParamPreconditions.checkNotEmpty(username, CodeEnum.FAIL.getCode(), "用户名不能为空");
        ParamPreconditions.checkNotEmpty(password, CodeEnum.FAIL.getCode(), "密码不能为空");
        String loginPwdMd5 = Digests.md5DigestAsHex(password);
        entity = paMemberRepository.findByMobileAndPwd(username, loginPwdMd5, Sysconst.REGIST_TRUE);
        if (entity == null)
            entity = paMemberRepository.findByLoginIdAndPwd(username, loginPwdMd5, Sysconst.REGIST_TRUE);
        if (entity == null)
            entity = paMemberRepository.findByEmailAndPwd(username, loginPwdMd5, Sysconst.REGIST_TRUE);
        ParamPreconditions.checkNotNull(entity, CodeEnum.FAIL.getCode(), "用户名或密码错误");
        MemberRegistDto dto = new MemberRegistDto();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }

    /**
     * 会员列表查询
     *
     * @param req
     * @return
     */
    public Result<List<PaMemberDto>> query(PaMemberReq req) {
        log.info("会员列表分页查询service req:{}", req);
        List<PaMember> memberlist = paMemberRepository.findAll(new Specification<PaMember>() {
            @Override
            public Predicate toPredicate(Root<PaMember> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = Lists.newArrayList();
                if (!Strings.isNullOrEmpty(req.getId())) {
                    list.add(cb.equal(root.get("id").as(String.class), req.getId()));
                }
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));

            }
        });
        List<PaMemberDto> dtos = Lists.newArrayList();
        for (PaMember pm : memberlist) {
            PaMemberDto dto = new PaMemberDto();
            BeanUtils.copyProperties(pm, dto);
            dtos.add(dto);
        }
        return Result.create(dtos);
    }

    /**
     * 会员列表分页查询
     *
     * @param req
     * @return
     */
    public Result<List<PaMemberDto>> queryByPage1(PaMemberReq req) {
        log.info("会员列表分页查询service req:{}", req);
        Pageable p = new PageRequest(req.getPageIndex() - 1, req.getPageSize(), new Sort(Direction.DESC, "updatetime"));
        Page<PaMember> page = paMemberRepository.findAll(new Specification<PaMember>() {
            @Override
            public Predicate toPredicate(Root<PaMember> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = Lists.newArrayList();
                if (!Strings.isNullOrEmpty(req.getId())) {
                    list.add(cb.equal(root.get("id").as(String.class), req.getId()));
                }
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));

            }
        }, p);
        List<PaMember> memberlist = page.getContent();
        List<PaMemberDto> dtos = Lists.newArrayList();
        for (PaMember pm : memberlist) {
            PaMemberDto dto = new PaMemberDto();
            BeanUtils.copyProperties(pm, dto);
            dtos.add(dto);
        }
        return Result.createPage(dtos, req.getPageIndex(), req.getPageSize(), page.getTotalElements());
    }

    public Result<List<PaMemberDto>> queryByPage(PaMemberReq req) {
        log.info("会员按代理分页查询【service】req:{}", req);
        String str = paAgentService.queryAryId(req.getAgentId());
        String sql = "select "
                + "pm.id as id,"
                + "pm.mobile as mobile,"
                + "pm.login_id as loginId,"
                + "pm.openid as openid,"
                + "pm.login_pwd as loginPwd,"
                + "pm.email as email,"
                + "pm.id_type as idType,"
                + "pm.id_no as idNo,"
                + "pm.id_spe_type as idSpeType,"
                + "pm.id_spe_no as idSpeNo,"
                + "pm.name as name,"
                + "pm.sex as sex,"
                + "pm.birthday as birthday,"
                + "pm.age as age,"
                + "pm.nick_name as nickName,"
                + "pm.province_code as provinceCode,"
                + "pm.province_name as provinceName,"
                + "pm.city_code as cityCode,"
                + "pm.city_name as cityName,"
                + "pm.area_code as areaCode,"
                + "pm.area_name as areaName,"
                + "pm.address as address,"
                + "pm.regist_flg as registFlg,"
                + "pm.balance as balance,"
                + "pm.createtime as createtime,"
                + "pm.updatetime as updatetime "
                + "from  yw_agent_member yam inner join pa_member pm on (yam.member_id = pm.id) inner join pa_agent pa on (yam.agent_id = pa.id) where 1=1";
        StringBuilder sb = new StringBuilder();
        if (!Strings.isNullOrEmpty(req.getAgentId())) {
            sb.append(" and pa.id = ").append(req.getAgentId());
        }
        if (!Strings.isNullOrEmpty(req.getId())) {
            sb.append(" and pm.id = ").append(req.getId());
        }
        if (!Strings.isNullOrEmpty(req.getMobile())) {
            sb.append(" and pm.mobile = ").append(req.getMobile());
        }
        sb.append(" and  yam.agent_id in (" + str + ")");
        sb.append(" ORDER BY yam.createtime DESC");
        JdbcPage<PaMemberDto> page = new JdbcPage<>(sql + sb.toString(), req.getPageSize(), req.getPageIndex(), jdbcTemplate, PaMemberDto.class);
        System.out.println(sql);
        return Result.createPage(page.getPage(), req.getPageSize(), req.getPageIndex(), page.getCount());

    }

    /**
     * 添加客户
     */
    public PaMemberDto add(String mobile, String openid) {
        log.info("绑定手机号mobile:{},openid:{}", mobile, openid);
        ParamPreconditions.checkNotEmpty(mobile, CodeEnum.FAIL.getCode(), "手机号不能为空");
        ParamPreconditions.checkNotEmpty(openid, CodeEnum.FAIL.getCode(), "openid不能为空");
        PaMember member = paMemberRepository.findByMobile(mobile);
        if (member == null)
            member = paMemberRepository.findPaMemberByOpenid(openid);
        if (member == null) {
            PaMemberDto dto = new PaMemberDto();
            PaMember newMember = new PaMember();
            String id = idGeneratorService.generateMemberId();
            newMember.setId(id);
            newMember.setMobile(mobile);
            newMember.setOpenid(openid);
            newMember.setLoginPwd(Digests.md5DigestAsHex(Sysconst.DefaultPwd));
            newMember = paMemberRepository.saveAndFlush(newMember);
            BeanUtils.copyProperties(newMember, dto);
            dto.setId(id);
            return dto;
        } else {
            PaMemberDto dto = new PaMemberDto();
            member.setOpenid(openid);
            member.setMobile(mobile);
            member = paMemberRepository.saveAndFlush(member);
            BeanUtils.copyProperties(member, dto);
            return dto;
        }
    }

    /**
     * 添加客户
     */
    public Result<String> updateNickDetail(WebRegistDetailReq req) {
        log.info("更新微信公众号信息req:{}", req);
        ParamPreconditions.checkMemberPrimiaryValid(req.getMemberId(), req.getMobile(), req.getOpenid(), null);
        PaMember member = paMemberRepository.findOne(req.getMemberId());
        if (member == null && !Strings.isNullOrEmpty(req.getMobile()))
            member = paMemberRepository.findByMobile(req.getMobile());
        if (member == null && !Strings.isNullOrEmpty(req.getOpenid()))
            member = paMemberRepository.findPaMemberByOpenid(req.getOpenid());
        ParamPreconditions.checkNotNull(member, CodeEnum.FAIL.getCode(), "未找到会员信息");
        member.setNickName(req.getNickname());
        member.setNickSex(req.getSex());
        member.setNickLanguage(req.getLanguage());
        member.setNickCity(req.getCity());
        member.setNickProvince(req.getProvince());
        member.setNickCountry(req.getCountry());
        member.setNickHeadimgurl(req.getHeadimgurl());
        member.setCreatetime(DateTimes.nowDateTime());
        member.setUpdatetime(DateTimes.nowDateTime());
        paMemberRepository.saveAndFlush(member);
        return Result.create("保存成功");
    }

    /**
     * 添加客户
     */
    public Result<PaMemberNickDto> queryNickDetail(String openid, String mobile, String memberId) {
        log.info("查询微信详情【service】openid:{},mobile:{},memberId:{}", openid, mobile, memberId);
        PaMember member = null;
        if (!Strings.isNullOrEmpty(openid))
            member = paMemberRepository.findPaMemberByOpenid(openid);
        if (Objects.isNull(member) && !Strings.isNullOrEmpty(mobile))
            member = paMemberRepository.findByMobile(mobile);
        if (Objects.isNull(member) && !Strings.isNullOrEmpty(memberId))
            member = paMemberRepository.findOne(memberId);
        ParamPreconditions.checkNotNull(member, CodeEnum.FAIL.getCode(), "未找到会员信息");
        PaMemberNickDto dto = new PaMemberNickDto();
        dto.setId(member.getId());
        dto.setMobile(member.getMobile());
        dto.setOpenid(member.getOpenid());
        dto.setName(member.getNickName());
        dto.setSex(member.getNickSex());
        dto.setLanguage(member.getNickLanguage());
        dto.setCity(member.getNickCity());
        dto.setProvince(member.getNickProvince());
        dto.setCountry(member.getNickCountry());
        dto.setHeadimgurl(member.getNickHeadimgurl());
        dto.setCreatetime(member.getCreatetime());
        dto.setUpdatetime(member.getUpdatetime());
        return Result.create(dto);
    }

    public PaMemberDto findOne(String id) {
        PaMember member = paMemberRepository.getOne(id);
        PaMemberDto dto = new PaMemberDto();
        BeanUtils.copyProperties(member, dto);
        return dto;
    }

    /**
     * 查询会员信息
     *
     * @param id
     * @param mobile
     * @param openid
     * @param loginId
     * @param email
     * @param idNo
     * @return
     */
    public PaMember findOne(String id, String mobile, String openid, String loginId, String email, String idNo) {
        PaMember member = null;
        if (!Strings.isNullOrEmpty(id))
            member = paMemberRepository.findOne(id);
        if (Objects.isNull(member) && !Strings.isNullOrEmpty(mobile))
            member = paMemberRepository.findByMobile(mobile);
        if (Objects.isNull(member) && !Strings.isNullOrEmpty(openid))
            member = paMemberRepository.findPaMemberByOpenid(openid);
        if (Objects.isNull(member) && !Strings.isNullOrEmpty(loginId))
            member = paMemberRepository.findByLoginId(loginId);
        if (Objects.isNull(member) && !Strings.isNullOrEmpty(email))
            member = paMemberRepository.findByEmail(email);
        if (Objects.isNull(idNo) && !Strings.isNullOrEmpty(idNo))
            member = paMemberRepository.findByIdNo(idNo);
        return member;
    }

    /**
     * 添加客户
     */
    public PaMemberDto add(PaMemberDto dto) {
        PaMember member = new PaMember();
        String id = idGeneratorService.generateMemberId();
        dto.setId(id);
        dto.setLoginPwd(Digests.md5DigestAsHex(Sysconst.DefaultPwd));
        BeanUtils.copyProperties(dto, member);
        member = paMemberRepository.save(member);
        dto.setId(id);
        return dto;
    }

    /**
     * 修改客户信息
     *
     * @param dto
     * @return
     */
    public PaMemberDto update(PaMemberDto dto) {
        PaMember member = paMemberRepository.findOne(dto.getId());
        ParamPreconditions.checkArgument(member != null, CodeEnum.FAIL.getCode(), "未找到会员信息");
        PaMember newMember = new PaMember();
        BeanUtils.copyProperties(dto, newMember);
        newMember.setId(member.getId());
        newMember.setMobile(member.getMobile());
        newMember.setLoginId(member.getLoginId());
        newMember.setEmail(member.getEmail());
        newMember.setLoginPwd(member.getLoginPwd());
        newMember = paMemberRepository.save(newMember);
        BeanUtils.copyProperties(dto, newMember);
        return dto;
    }

    public PaMemberDto update1(PaMemberDto dto) {
        PaMember member = paMemberRepository.findOne(dto.getId());
        ParamPreconditions.checkArgument(member != null, CodeEnum.FAIL.getCode(), "未找到会员信息");
        BeanUtils.copyProperties(dto, member);
        member = paMemberRepository.save(member);
        BeanUtils.copyProperties(dto, member);
        return dto;
    }

    /**
     * 更新客户
     */
    public PaMember update(PaMember member) {
        return paMemberRepository.saveAndFlush(member);
    }
}
